package sparrowGui
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	
	import sparrowGui.impl.IScrollPan;
	import sparrowGui.item.CListItem;
	import sparrowGui.item.Item;
	import sparrowGui.skin.TreeChildItemSkin;
	import sparrowGui.skin.TreeItemSkin;
	import sparrowGui.utils.PubFun;

	public class XMLTree extends VHList implements IScrollPan
	{
		public static const AUTO_INDEX_ATTR:String = "xIndex";		//自动生成的属性名
		private var _itemSkinArr:Array;
		private var _childItemSkin:Class;
		/**
		 * @param data			此对象为xml,格式如下:
		 * <tree>
		 * 		<node name='Lv1'>
		 * 			<node name='lv2_1' />
		 * 			<node name='lv2_2' />
		 * 		</node>
		 * 		<node name='Lv1'>
		 * 			<node name='lv2_1' />
		 * 			<node name='lv2_2' />
		 * 		</node>
		 * </tree>
		 * @param rootItemSkin	树的父项皮肤类
		 * @param childItemSkin	树的子项皮肤类
		 * @param vars
		 */
		public function XMLTree(dataXML:XML,rootItemSkin:Class=null,childItemSkin:Class=null,vars:Object=null)
		{
			_childItemSkin = (childItemSkin!=null)?childItemSkin:TreeChildItemSkin;
			rootItemSkin = (rootItemSkin!=null)?rootItemSkin:TreeItemSkin;
			
			vars = vars || SparrowGUI.getIns().treeVars;
			dataXML = dataXML || new XML();
			super(dataXML,rootItemSkin,vars);
			
			initDataXML();
		}
		
		override public function update(data:Object):void
		{
			if(!data || !(data is XML)) return;
			_itemsData = data;
			_selectedIndexs = [];
			initDataXML();
			nextDraw();
		}
		
		// 初始数据
		private function initDataXML():void
		{
			if(!itemsData || !(itemsData is XML)) return;
			var index:int = 0;
			for each (var childXML:Object in (itemsData as XML)..node) 
			{
				childXML.@[AUTO_INDEX_ATTR] = index++;	//给xml加上id,方便找父级节点
				childXML.@selected = 0;	//初始时所有节点选择为0
			}
		}
		
		override protected function makeListItems():void
		{
			PubFun.clearDisp(contDP);
			if(!itemsData || !(itemsData as XML).children().length()) return;
			recursionCreateItem((itemsData as XML).children()[0]);
			arrangeItems();
		}
		
		// 通过递归函数将xml数据生成项
		private function recursionCreateItem(childXML:XML=null,index:int=0):void
		{
			var itemSkin:Sprite,cls:Class;
			if(childXML.children().length() || !childXML.parent().parent()) cls = _itemSkinCla;
			else cls = _childItemSkin;
			
			itemSkin = (_itemSkinCla!=null && (style.itemClass!=CListItem))?(new cls() as Sprite):null;
			var _itCla:Class = style.itemClass || Item;
			var oItem:Item = new _itCla(null,itemSkin,null);
			contDP.addChild(oItem);
//			childXML.@[AUTO_INDEX_ATTR] = index++;	//给xml加上id,方便找父级节点
//			childXML.@selected = 0;	//初始时所有节点选择为0
			var itm:Item = createItem(String(childXML.@name),int(childXML.@[AUTO_INDEX_ATTR]),oItem);
			if(String(childXML.parent().@[AUTO_INDEX_ATTR])!=''){
				itm.visible = false;
//				itm.scaleX = itm.scaleY = 0;
			}
			
			if(childXML.children().length()){
				recursionCreateItem(childXML.children()[0],index);
				return;
			}
			// 父节点为空,根节点,且下一节点也为空
			if(!childXML.parent()) return;

			var ppXML:XML = getNextNode(childXML);
			if(!ppXML) return;
			recursionCreateItem(ppXML,index);
		}
		
		// 递归获取上一级且有下一节点的xml的下级节点
		private function getNextNode(tXml:XML):XML
		{
			if(!tXml.parent()) return null;
			if(tXml.parent().children().length()>(tXml.childIndex()+1))
				return (tXml.parent().children()[tXml.childIndex()+1]);
			else return getNextNode(tXml.parent());
		}
		
		override protected function createItem(data:Object,selIndex:int,oItem:Item=null):Item
		{
			oItem.update(data);
			oItem.index = selIndex;
			oItem.name = "ListItem" + selIndex;
			oItem.visible = true;
			
			if(style.autoSort && style.itemOdds)
				oItem.autoFill(style.itemOdds);
			
			if(_selectedIndexs.indexOf(oItem.index)>=0) oItem.selected=true;
			else oItem.selected=false;
			
			if(hasEventListener(RadioEvent.ITEM_UPDATE))
				dispatchEvent(new RadioEvent(RadioEvent.ITEM_UPDATE,oItem));
			
			return oItem;
		}
		
		// 递归获取节点的深度,用于计算缩进
		private function getNodeLv(idx:int,lv:int=0):int
		{
			var iXml:XML=itemsData as XML;
			var theNode:XMLList = iXml..*.(@[AUTO_INDEX_ATTR]==idx) as XMLList;
			if(!theNode.parent() || String(theNode.parent().@[AUTO_INDEX_ATTR])==''){
				return lv;
			}else return getNodeLv(int(theNode.parent().@[AUTO_INDEX_ATTR]),++lv);
		}
		
		override protected function arrangeItems():void
		{
			var tmpY:int = 0, iXml:XML = itemsData as XML;
			for each(var xx:Object in iXml..node){
				var index:int = int(xx.@[AUTO_INDEX_ATTR]);
				var oItem:Item = getItemByIndex(index);
				if(!oItem) continue;
				
				if(hasParentUnSelect(xx.parent())){
					oItem.y = oItem.x = 0;
					oItem.visible = false;
				}else{
					oItem.y = tmpY;
					oItem.x = getNodeLv(oItem.index)*style.indet;
					tmpY = tmpY + style.spacing + (style.rowHeight?style.rowHeight:oItem.height);
					oItem.visible = true;
				}
				
			}
/*			for(var i:int;i<contDP.numChildren;i++){
				var dp:Item = contDP.getChildAt(i) as Item;
				if(!dp.visible){
					dp.y = dp.x = 0;
					continue;
				}
				dp.y = tmpY;
				dp.x = getNodeLv(dp.index)*style.indet;
				tmpY = tmpY + style.spacing + (style.rowHeight?style.rowHeight:dp.height);
			}*/
		}
		
		//激活滚动条
		override protected function activeScroll(step:Number=0,disHeight:Number=0):void
		{
			var len:int = 0;
			for(var i:int=0;i<contDP.numChildren;i++){
				if(contDP.getChildAt(i).visible) len++;
			}
			step = contDP.height/len;
			disHeight = (((contDP.width-maskDP.width)>0)?VScrollBar.THICKNESS:0);
			super.activeScroll(step,disHeight);
			
			disHeight = (((contDP.height-maskDP.height)>0)?VScrollBar.THICKNESS:0);
			activeHBar(disHeight);
		}
		
		override public function addSelectedIndex(value:int):void
		{
			unSelectAll();
			var iXml:XML = itemsData as XML;
			var sel:int = int(iXml..node.(int(@[AUTO_INDEX_ATTR])==value).@selected);
			iXml..node.(int(@[AUTO_INDEX_ATTR])==value).@selected = int(!sel);
			super.addSelectedIndex(value);
		}
		
		/**
		 * 关闭全选
		 */
		override public function selectAll():void
		{
			return;
		}
		
		/**
		 * 将所有子节点对象的项取消选择
		 */
		override public function unSelectAll():void
		{
			var iXml:XML=itemsData as XML,theNode:XMLList;
			for each(var xx:Object in iXml..node){
				var index:int = int(xx.@[AUTO_INDEX_ATTR]);
				if(!xx.children().length())
					xx.@selected = 0;
				if((_selectedIndexs.indexOf(index))>=0)
					_selectedIndexs.splice((_selectedIndexs.indexOf(index)),1);
			}
			arrangeItems();
		}
		
		/**
		 * 刷新显示层次 
		 */
		override protected function selectFresh():void
		{
			var iXml:XML=itemsData as XML,theNode:XMLList;
			var srY:Number=contDP.y,hv:Boolean=_hScroll.visible,srH:Number=contDP.height;
			for each(var xx:Object in iXml..node){
				var index:int = int(xx.@[AUTO_INDEX_ATTR]);
				var oItem:Item = getItemByIndex(index);
				if(!oItem) continue;
				if(int(xx.@selected==0)){
					oItem.selected = false;
				}else oItem.selected = true;
				
				if(hasParentUnSelect(xx.parent()))
					oItem.visible = false;
				else
					oItem.visible = true;
			}
			
			if(!contDP.numChildren) return;
			arrangeItems();
			
			if(srH==contDP.height) return;
			activeScroll();
			addEvt();
			
			_vScroll.value = (Math.abs(srY-((!hv && _hScroll.visible)?_hScroll.height:0))) / scrollDist;
			_vScroll.onMoveSlider(null);
		}
		
		// 是否有上级在被选中数组里,向节点的上级节点遍历查找是否有节点在选中组的父节点
		private function hasParentUnSelect(node:XML):Boolean
		{
			// n@[AUTO_INDEX_ATTR]==''表示该节点为根节点  
			if(!node.parent() || String(node.@[AUTO_INDEX_ATTR])=='') return false;
			if(int(node.@selected)==0)
				return true;
			else return hasParentUnSelect(node.parent());
		}
		
		/**
		 * 设置滚动到容器的index位置
		 * @param index
		 */		
		override public function setScrollIndex(index:int):void
		{
			var oItem:Item = getItemByIndex(index);
			if(!oItem) return;
			var val:Number = (oItem.y) / (contDP.height - style.height);
			val = val>1?1:val;
			_vScroll.value = val;
			_vScroll.onMoveSlider(null);
		}
		
		
		/**
		 * 设置子项缩进 
		 * @param value
		 */
		public function set indet(value:int):void
		{
			style.indet = value;
		}
		
		
		
		/**
		 * 获取子项缩进 
		 * @param value
		 */
		public function get indet():int
		{
			return style.indet;
		}
	}
}